//
// File:        rm_internal.h
// Description: Some declarations used only by the RM component
// Authors:     Haris Wang (dynmiw@gmail.com)
//
//
#include <cstring>
#include "redbase.h"
#include "rm.h"

#ifndef RM_INTERNAL_H
#define RM_INTERNAL_H

//
// RM_PageHdr: Header structure for pages
// 
#define RM_PAGE_LIST_END  -1       // end of list of free pages
#define RM_PAGE_FULLY_USED      -2       // page is fully used with no free slots
struct RM_PageHdr {
    int nextFree;

    char *freeSlotMap;
    int numTotSlots;
    int numFreeSlots;

RM_PageHdr(int numSlots) : numTotSlots(numSlots), numFreeSlots(numSlots)
{
    freeSlotMap = new char[this->mapsize()];
}

~RM_PageHdr()
{
    delete [] freeSlotMap;
}

int size() const
{
    return sizeof(nextFree) + sizeof(numTotSlots) + sizeof(numFreeSlots)
        + bitmap(numTotSlots).NumChars*sizeof(char);
}

int mapsize() const
{
    return this->size() - sizeof(nextFree)
        - sizeof(numTotSlots) - sizeof(numFreeSlots);
}

int to_buf(char *& buf) const
{
    //
    // send PageHdr to 'buf'
    //
    memcpy(buf, &nextFree, sizeof(nextFree));
    memcpy(buf+sizeof(nextFree), &numTotSlots, sizeof(numTotSlots));
    memcpy(buf+sizeof(nextFree)+sizeof(numTotSlots),
        &numFreeSlots, sizeof(numFreeSlots));
    memcpy(buf+sizeof(nextFree)+sizeof(numTotSlots)+sizeof(numFreeSlots),
        freeSlotMap, this->mapsize()*sizeof(char));
    return 0;
}

int from_buf(const char *buf)
{
    //
    // set PageHdr with 'buf'
    //
    memcpy(&nextFree, buf, sizeof(nextFree));
    memcpy(&numTotSlots, buf+sizeof(nextFree), sizeof(numTotSlots));
    memcpy(&numFreeSlots, buf+sizeof(nextFree)+sizeof(numTotSlots), sizeof(numFreeSlots));
    memcpy(freeSlotMap, buf+sizeof(nextFree)+sizeof(numTotSlots)+sizeof(numFreeSlots),
        this->mapsize()*sizeof(char));
    return 0;
}

};

//
// bitmap: provides bitmap structure for each page
//
class bitmap {
private:
    unsigned int size;
    char* buffer;
public:
    unsigned int NumChars;

    bitmap(int numBits, char* buf=NULL);
    ~bitmap();

    void set(unsigned int bitNum=0-1, bool sign=0);
    bool test(unsigned int bitNumber) const;

    RC to_char_buf(char * buf, int len) const;
    RC getSize() const;
};

//
// Predicate
// 
class Predicate {
public:
  Predicate() {}
  ~Predicate() {}

  Predicate(AttrType   attrTypeIn,       
            int        attrLengthIn,
            int        attrOffsetIn,
            CompOp     compOpIn,
            void       *valueIn,
            ClientHint pinHintIn) 
    {
      attrType = attrTypeIn;       
      attrLength = attrLengthIn;
      attrOffset = attrOffsetIn;
      compOp = compOpIn;
      value = valueIn;
      pinHint = pinHintIn;
    }

  CompOp initOp() const { return compOp; }
  bool eval(const char *buf, CompOp c) const;
  bool eval(const char *lhsBuf, const char* rhsValue, CompOp c) const;

 private:
  AttrType   attrType;
  int        attrLength;
  int        attrOffset;
  CompOp     compOp;
  void*      value;
  ClientHint pinHint;
};

#endif